home *** CD-ROM | disk | FTP | other *** search
/ PC Graphics Unleashed / PC Graphics Unleashed.iso / ch01 / vesa.c < prev    next >
Text File  |  1993-12-06  |  5KB  |  147 lines

  1. /**
  2.  ** VESA.C ---- VESA compatible paging routines
  3.  **
  4.  ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  5.  ** Copyright (C) 1992 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
  6.  ** Copyright (C) 1993 Grzegorz Mazur, gbm@ii.pw.edu.pl
  7.  **
  8.  ** This file is distributed under the terms listed in the document
  9.  ** "copying.dj", available from DJ Delorie at the address above.
  10.  ** A copy of "copying.dj" should accompany this file; if not, a copy
  11.  ** should be available from where this file was obtained.  This file
  12.  ** may not be distributed without a verbatim copy of "copying.dj".
  13.  **
  14.  ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  15.  ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16.  **/
  17.  
  18. int  VESA_win_write = 0;    /* VESA window index of the writable page */
  19. int  VESA_win_read  = (-1);    /* VESA window index of the readable page */
  20.  
  21. void far paging_routine(void)
  22. {
  23.     return;
  24. }
  25.  
  26. void far VESA_paging_routine(void)
  27. {
  28.     asm push    ds;
  29.     asm push    es;
  30.     asm mov        cl,BYTE PTR cs:[driver_header.page_gran_shift];
  31.     asm mov        dl,al;
  32.     asm xor        dh,dh;
  33.     asm shl        dx,cl;                /* DX: write window (A or B) index */
  34.     asm mov        al,ah;
  35.     asm xor        ah,ah;
  36.     asm shl        ax,cl;                /* AX: read window index */
  37.     asm mov        bx,WORD PTR cs:[VESA_win_write];    /* index (A or B) of write window */
  38.     asm cmp        bx,(-1);                /* set it ? */
  39.     asm je        set_read_window;
  40.     asm push    ax;                    /* save read window */
  41.     asm mov        ax,0x4f05;
  42.     asm call    DWORD PTR cs:[driver_header.VESA_paging_fnc];
  43.     asm pop        ax;
  44. set_read_window:
  45.     asm mov        bx,WORD PTR cs:[VESA_win_read];    /* index (A or B) of read window */
  46.     asm cmp        bx,(-1);                /* set it ? */
  47.     asm je        paging_done;
  48.     asm mov        dx,ax;
  49.     asm mov        ax,0x4f05;
  50.     asm call    DWORD PTR cs:[driver_header.VESA_paging_fnc];
  51. paging_done:
  52.     asm pop        es;
  53.     asm pop        ds;
  54.     asm mov        al,8;                /* reconfig GR CTRL port for mask writes */
  55.     asm mov        dx,0x3ce;                /* GRX expects it in 16 color modes, and */
  56.     asm out        dx,al;                /* the paging func may have changed it */
  57.     return;
  58. }
  59.  
  60. int setup_VESA_paging(GrModeEntry *md)
  61. {
  62.     ModeInfoBlock *mb = VESAgetModeInfo(md->mode.vdr.BIOS_mode);
  63.     int winsize,wingran,Aattr,Battr,Sdiff;
  64.  
  65.     if(!mb || !(mb->ModeAttributes & MODE_ISGRAPHICS)) {
  66.         VESA_win_read  = (-1);
  67.         VESA_win_write = (-1);
  68.         driver_header.VESA_paging_fnc = 0L;
  69.         driver_header.paging_routine  = FP_OFF(paging_routine);
  70.         return(GRD_NO_RW);
  71.     }
  72.  
  73.     /* size and granularity must be pwr of 2! */
  74.     for(winsize = 0; (1 << winsize) < mb->WinSize;          winsize++) ;
  75.     for(wingran = 0; (1 << wingran) < mb->WinGranularity; wingran++) ;
  76.     if((1 << winsize) != mb->WinSize)     return(-1);
  77.     if((1 << wingran) != mb->WinGranularity) return(-1);
  78.  
  79.     /* check window attributes */
  80.     Aattr = mb->WinAAttributes;
  81.     Battr = mb->WinBAttributes;
  82.     Sdiff = mb->WinBSegment - mb->WinASegment;
  83.     Aattr &= (Aattr & WIN_SUPPORTED) ? (WIN_READABLE | WIN_WRITABLE) : 0;
  84.     Battr &= (Battr & WIN_SUPPORTED) ? (WIN_READABLE | WIN_WRITABLE) : 0;
  85.  
  86.     /* cases with two adjacent split R/W pages (ATI) */
  87.     if((Aattr == (WIN_READABLE | WIN_WRITABLE)) &&
  88.        (Battr == (WIN_READABLE | WIN_WRITABLE)) &&
  89.        (Sdiff == ((1024 / 16) << winsize))) {
  90.         driver_header.wr_page_start = mb->WinASegment;
  91.         driver_header.rd_page_start = mb->WinBSegment;
  92.         VESA_win_write = 0;
  93.         VESA_win_read  = 1;
  94.     }
  95.     else if((Aattr == (WIN_READABLE | WIN_WRITABLE)) &&
  96.         (Battr == (WIN_READABLE | WIN_WRITABLE)) &&
  97.         (Sdiff == ((-1024 / 16) << winsize))) {
  98.         driver_header.wr_page_start = mb->WinBSegment;
  99.         driver_header.rd_page_start = mb->WinASegment;
  100.         VESA_win_write = 1;
  101.         VESA_win_read  = 0;
  102.     }
  103.  
  104.     /* cases with one full R and one full W page (Tseng 4000) */
  105.     else if((Aattr & WIN_READABLE) &&
  106.         (Battr & WIN_WRITABLE) &&
  107.         (Sdiff == 0)) {
  108.         driver_header.wr_page_start = mb->WinBSegment;
  109.         driver_header.rd_page_start = mb->WinASegment;
  110.         VESA_win_write = 1;
  111.         VESA_win_read  = 0;
  112.     }
  113.     else if((Aattr & WIN_WRITABLE) &&
  114.         (Battr & WIN_READABLE) &&
  115.         (Sdiff == 0)) {
  116.         driver_header.wr_page_start = mb->WinASegment;
  117.         driver_header.rd_page_start = mb->WinBSegment;
  118.         VESA_win_write = 0;
  119.         VESA_win_read  = 1;
  120.     }
  121.  
  122.     /* single page cases (Trident) */
  123.     else if(Aattr == (WIN_WRITABLE | WIN_READABLE)) {
  124.         driver_header.wr_page_start = mb->WinASegment;
  125.         driver_header.rd_page_start = 0xffff;
  126.         VESA_win_write = 0;
  127.         VESA_win_read  = (-1);
  128.     }
  129.     else if(Battr == (WIN_WRITABLE | WIN_READABLE)) {
  130.         driver_header.wr_page_start = mb->WinBSegment;
  131.         driver_header.rd_page_start = 0xffff;
  132.         VESA_win_write = 1;
  133.         VESA_win_read  = (-1);
  134.     }
  135.     /* cannot use the paging scheme of this card */
  136.     else return(-1);
  137.  
  138.     /* setup header variables */
  139.     driver_header.page_size_shift = winsize - 2;         /* in 4kByte units */
  140.     driver_header.page_gran_shift = winsize - wingran;
  141.     driver_header.line_offset     = mb->BytesPerScanLine;
  142.     driver_header.VESA_paging_fnc = mb->WinFuncPtr;
  143.     driver_header.paging_routine  = FP_OFF(VESA_paging_routine);
  144.     return((VESA_win_read == (-1)) ? GRD_NO_RW : GRD_RW_64K);
  145. }
  146.  
  147.